﻿//#include<iostream>
//#include<vector>
//#include<string>
//
//using namespace std;
//
//int main()
//{
//	initializer_list<double> il = { 1.0,2.0,3.9,4.8,2.3,9.6 };
//	initializer_list<string> ill = { "192","12" };
//	for (double e : il)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	for (string e : ill)
//	{
//		cout << e << endl;
//	}
//	return 0;
//}

//#include<iostream>
//#include<utility>
//
//using namespace std;
//int main()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常见的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//	cout << &c << endl;
//	cout << (void*)&s[0] << endl;
//	// 右值：不能取地址
//	double x = 1.1, y = 2.2;
//	// 以下⼏个10、x + y、fmin(x, y)、string("11111")都是常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//	string("11111");
//	//cout << &10 << endl;
//	//cout << &(x+y) << endl;
//	//cout << &(fmin(x, y)) << endl;
//	//cout << &string("11111") << endl;
//	return 0;
//}


//template <class _Ty>
//remove_reference_t<_Ty>&& move(_Ty&& _Arg)
//{ // forward _Arg as movable
//	return static_cast<remove_reference_t<_Ty>&&>(_Arg);
//}

//int main()
//{
//	// 左值：可以取地址
//	// 以下的p、b、c、*p、s、s[0]就是常见的左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//	double x = 1.1, y = 2.2;
//	// 左值引⽤给左值取别名
//	int& r1 = b;
//	int*& r2 = p;
//	int& r3 = *p;
//	string& r4 = s;
//	char& r5 = s[0];
//	// 右值引⽤给右值取别名
//	int&& rr1 = 10;
//	 double&& rr2 = x + y;
//	 double&& rr3 = fmin(x, y);
//	 string && rr4 = string("11111");
//	
//		 // 左值引⽤不能直接引⽤右值，但是const左值引⽤可以引⽤右值
//	 const int& rx1 = 10;
//	 const double& rx2 = x + y;
//	 const double& rx3 = fmin(x, y);
//	 const string & rx4 = string("11111");
//		 // 右值引⽤不能直接引⽤左值，但是右值引⽤可以引⽤move(左值)
//	 int&& rrx1 = move(b);
//	 int*&& rrx2 = move(p);
//	 int&& rrx3 = move(*p);
//	 string && rrx4 = move(s);
//	 string && rrx5 = (string&&)s;
//	
//		 // b、r1、rr1都是变量表达式，都是左值
//	 cout << &b << endl;
//	 cout << &r1 << endl;
//	 cout << &rr1 << endl;
//	
//		 // 这⾥要注意的是，rr1的属性是左值，所以不能再被右值引⽤绑定，除⾮move⼀下
//	int& r6 = r1;
//	 // int&& rrx6 = rr1;
//	 int&& rrx6 = move(rr1);
//	 return 0;
//}
//int main()
//{
//	 std::string s1 = "Test";
//	 // std::string&& r1 = s1; // 错误：不能绑定到左值
//		
//	 const std::string & r2 = s1 + s1; // OK：到 const 的左值引⽤延⻓⽣存期
//	 // r2 += "Test"; // 错误：不能通过到 const 的引⽤修改
//		
//    std::string && r3 = s1 + s1; // OK：右值引⽤延⻓⽣存期
//	r3 += "Test"; // OK：能通过到⾮ const 的引⽤修改
//	std::cout << r3 << '\n';
//	return 0;
//}
//#include<iostream>
//using namespace std;
//void f(int& x)
//{
//	std::cout << "左值引⽤重载 f(" << x << ")\n";
//}
//void f(const int& x)
//{
//	std::cout << "到 const 的左值引⽤重载 f(" << x << ")\n";
//}
//void f(int&& x)
//{
//	std::cout << "右值引⽤重载 f(" << x << ")\n";
//}
//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//	// 右值引⽤变量在⽤于表达式时是左值
//	int&& x = 1;
//	f(x); // 调⽤ f(int& x)
//	f(std::move(x)); // 调⽤ f(int&& x)
//	
//	 return 0;
//}

//#include<iostream>
//#include<string>
//#include<vector>
//using namespace std;
//
//class Solution {
//public:
//	// 传值返回需要拷贝
//	string addStrings(string num1, string num2) {
//		string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//		{
//			str += '1';
//	    }
//		reverse(str.begin(), str.end());
//
//		return str;
//	}
//};
//
//class Solution {
//public:
//	// 这⾥的传值返回拷贝代价就太⼤了
//	vector<vector<int>> generate(int numRows) {
//		vector<vector<int>> vv(numRows);
//		for (int i = 0; i < numRows; ++i)
//		{
//			vv[i].resize(i + 1, 1);
//		}
//		for (int i = 2; i < numRows; ++i)
//		{
//			for (int j = 1; j < i; ++j)
//			{
//				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//			}
//		}
//		return vv;
//	}
//};

//#define _CRT_SECURE_NO_WARNINGS 1
//#include<iostream>
//#include<assert.h>
//#include<string.h>
//#include<algorithm>
//using namespace std;
//namespace sl
//{
//    class string
//    {
//    public:
//        typedef char* iterator;
//        typedef const char* const_iterator;
//
//        iterator begin()
//        {
//            return _str;
//        }
//        iterator end()
//        {
//            return _str + _size;
//        }
//
//        const_iterator begin() const
//        {
//            return _str;
//        }
//
//        const_iterator end() const
//        {
//            return _str + _size;
//        }
//
//        string(const char* str = "")
//            :_size(strlen(str))
//            , _capacity(_size)
//        {
//            cout << "string(char* str)-构造" << endl;
//            _str = new char[_capacity + 1];
//            strcpy(_str, str);
//        }
//
//        void swap(string& s)
//        {
//            ::swap(_str, s._str);
//            ::swap(_size, s._size);
//            ::swap(_capacity, s._capacity);
//        }
//
//        string(const string& s)
//            :_str(nullptr)
//        {
//            cout << "string(const string& s) -- 拷贝构造" << endl;
//
//            reserve(s._capacity);
//            for (auto ch : s)
//            {
//                push_back(ch);
//            }
//        }
//
//        // 移动构造
//        string(string&& s)
//        {
//            cout << "string(string&& s) -- 移动构造" << endl;
//            swap(s);
//        }
//
//        string& operator=(const string& s)
//        {
//            cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
//            if (this != &s)
//            {
//                _str[0] = '\0';
//                _size = 0;
//
//                reserve(s._capacity);
//                for (auto ch : s)
//                {
//                    push_back(ch);
//                }
//            }
//
//            return *this;
//        }
//
//        // 移动赋值
//        string& operator=(string&& s)
//        {
//            cout << "string& operator=(string&& s) -- 移动赋值" << endl;
//            swap(s);
//            return *this;
//        }
//
//        ~string()
//        {
//            cout << "~string() -- 析构" << endl;
//            delete[] _str;
//            _str = nullptr;
//        }
//
//        char& operator[](size_t pos)
//        {
//            assert(pos < _size);
//            return _str[pos];
//        }
//
//        void reserve(size_t n)
//        {
//            if (n > _capacity)
//            {
//                char* tmp = new char[n + 1];
//                if (_str)
//                {
//                    strcpy(tmp, _str);
//                    delete[] _str;
//                }
//                _str = tmp;
//                _capacity = n;
//            }
//        }
//
//        void push_back(char ch)
//        {
//            if (_size >= _capacity)
//            {
//                size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//                reserve(newcapacity);
//            }
//
//            _str[_size] = ch;
//            ++_size;
//            _str[_size] = '\0';
//        }
//
//        string& operator+=(char ch)
//        {
//            push_back(ch);
//            return *this;
//        }
//
//        const char* c_str() const
//        {
//            return _str;
//        }
//
//        size_t size() const
//        {
//            return _size;
//        }
//    private:
//        char* _str = nullptr;
//        size_t _size = 0;
//        size_t _capacity = 0;
//    };
//}
//
//int main()
//{
//    sl::string s1("xxxxx");
//    // 拷贝构造
//    sl::string s2 = s1;
//    // 构造+移动构造，优化后直接构造
//    sl::string s3 = sl::string("yyyyy");
//    // 移动构造
//    sl::string s4 = move(s1);
//    cout << "******************************" << endl;
//
//    return 0;
//}

//#include<iostream>
//#include<string>
//#include<vector>
//using namespace std;
//
//namespace sl
//{
//    string addStrings(string num1, string num2)
//    {
//        string str;
//        int end1 = num1.size() - 1, end2 = num2.size() - 1;
//        int next = 0;
//        while (end1 >= 0 || end2 >= 0)
//        {
//            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//
//            int ret = val1 + val2 + next;
//            next = ret / 10;
//            ret = ret % 10;
//
//            str += ('0' + ret);
//        }
//        if (next == 1)
//            str += '1';
//        reverse(str.begin(), str.end());
//        cout << "******************************" << endl;
//        return str;
//    }
//}
//
//// 场景1
////int main()
////{
////    string ret = sl::addStrings("11111", "2222");
////    cout << ret.c_str() << endl;
////    return 0;
////}
//
////// 场景2
//int main()
//{
//    string ret;
//    ret = sl::addStrings("11111", "2222");
//    cout << ret.c_str() << endl;
//    return 0;
//}

//#include <iostream>
//using namespace std;
//
//// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
//template<class T>
//void f1(T& x)
//{
//}
//
//// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
//template<class T>
//void f2(T&& x)
//{
//}
//
//int main()
//{
//    typedef int& lref;
//    typedef int&& rref;
//    int n = 0;
//    lref& r1 = n; // r1 的类型是 int&
//    lref&& r2 = n; // r2 的类型是 int&
//    rref& r3 = n; // r3 的类型是 int&
//    rref&& r4 = 1; // r4 的类型是 int&&
//
//    // 没有折叠->实例化为void f1(int& x)
//    f1<int>(n);
//    f1<int>(0); // 报错
//
//    // 折叠->实例化为void f1(int& x)
//    f1<int&>(n);
//    f1<int&>(0); // 报错
//
//    // 折叠->实例化为void f1(int& x)
//    f1<int&&>(n);
//    f1<int&&>(0); // 报错
//
//    // 折叠->实例化为void f1(const int& x)
//    f1<const int&>(n);
//    f1<const int&>(0);
//
//    // 折叠->实例化为void f1(const int& x)
//    f1<const int&&>(n);
//    f1<const int&&>(0);
//
//    // 没有折叠->实例化为void f2(int&& x)
//    f2<int>(n); // 报错
//    f2<int>(0);
//
//    // 折叠->实例化为void f2(int& x)
//    f2<int&>(n);
//    f2<int&>(0); // 报错
//
//    // 折叠->实例化为void f2(int&& x)
//    f2<int&&>(n); // 报错
//    f2<int&&>(0);
//
//    return 0;
//}
//
//template<class T>
//void Function(T&& t)
//{
//    int a = 0;
//    T x = a;
//    //x++;
//    cout << &a << endl;
//    cout << &x << endl << endl;
//}
//
//int main()
//{
//    // 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//    Function(10); // 右值
//
//    int a;
//    // a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//    Function(a); // 左值
//
//    // std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//    Function(std::move(a)); // 右值
//
//    const int b = 8;
//    // a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//    // 所以Function内部会编译报错，x不能++
//    Function(b); // const 左值
//
//    // std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//    // 所以Function内部会编译报错，x不能++
//    Function(std::move(b)); // const 右值
//
//    return 0;
//}

//#include<iostream>
//using namespace std;
//
//template <class _Ty>
//_Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
//{ // forward an lvalue as either an lvalue or an rvalue
//	return static_cast<_Ty&&>(_Arg);
//}
//void Fun(int& x) { cout << "左值引⽤" << endl; }
//void Fun(const int& x) { cout << "const 左值引⽤" << endl; }
//void Fun(int&& x) { cout << "右值引⽤" << endl; }
//void Fun(const int&& x) { cout << "const 右值引⽤" << endl; }
//template<class T>
//void Function(T&& t)
//{
//	Fun(t);
//	//Fun(forward<T>(t));
//}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//	const int b = 8;
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//	Function(b); // const 左值
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	Function(std::move(b)); // const 右值
//	return 0;
//}


//#include<iostream>
//#include<string>
//using namespace std;
//
//template <class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("xxxxx")); // 包⾥有2个参数
//	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数
//	return 0;
//}
//// 原理1：编译本质这⾥会结合引⽤折叠规则实例化出以下四个函数
//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);
//// 原理2：更本质去看没有可变参数模板，我们实现出这样的多个函数模板才能⽀持
//// 这⾥的功能，有了可变参数模板，我们进⼀步被解放，他是类型泛化基础
//// 上叠加数量变化，让我们泛型编程更灵活。
//void Print();
//template <class T1>
//void Print(T1&& arg1);
//template <class T1, class T2>
//void Print(T1&& arg1, T2&& arg2);
//template <class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3);
//// ...

// 可变模板参数
// 参数类型可变
// 参数个数可变
// 打印参数包内容
//template <class ...Args>
//void Print(Args... args)
//{
// // 可变参数模板编译时解析
// // 下⾯是运⾏获取和解析，所以不⽀持这样⽤
// cout << sizeof...(args) << endl;
// for (size_t i = 0; i < sizeof...(args); i++)
// {
// cout << args[i] << " ";
// }
// cout << endl;
//}

//#include<iostream>
//using namespace std;
//
//void ShowList()
//{
//	// 编译器时递归的终⽌条件，参数包是0个时，直接匹配这个函数
//	cout << endl;
//}
//
//template <class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	cout << x << " ";
//	// args是N个参数的参数包
//	// 调⽤ShowList，参数包的第⼀个传给x，剩下N-1传给第⼆个参数包
//	ShowList(args...);
//}
//
//// 编译时递归推导解析参数
//template <class ...Args>
//void Print(Args... args)
//{
//	ShowList(args...);
//}
//
//int main()
//{
//	Print();
//	Print(1);
//	Print(1, string("xxxxx"));
//	Print(1, string("xxxxx"), 2.2);
//
//	return 0;
//}
//
////template <class T, class ...Args>
////void ShowList(T x, Args... args)
////{
//// cout << x << " ";
//// Print(args...);
////}
//
//// Print(1, string("xxxxx"), 2.2);调⽤时
//// 本质编译器将可变参数模板通过模式的包扩展，编译器推导的以下三个重载函数函数
////void ShowList(double x)
////{
//// cout << x << " ";
//// ShowList();
////}
////
////void ShowList(string x, double z)
////{
//// cout << x << " ";
//// ShowList(z);
////}
////
////void ShowList(int x, string y, double z)
////{
//// cout << x << " ";
//// ShowList(y, z);
////}
//
////void Print(int x, string y, double z)
////{
//// ShowList(x, y, z);
////}
//
//template <class T>
//const T& GetArg(const T& x)
//{
//	cout << x << " ";
//	return x;
//}
//
//template <class ...Args>
//void Arguments(Args... args)
//{
//}
//
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments
//	Arguments(GetArg(args)...);
//}
//
//// 本质可以理解为编译器编译时，包的扩展模式
//// 将上⾯的函数模板扩展实例化为下⾯的函数
//// 是不是很抽象，C++11以后，只能说委员会的⼤佬设计语法思维跳跃得太厉害
////void Print(int x, string y, double z)
////{
////    Arguments(GetArg(x), GetArg(y), GetArg(z));
////}
//
//int main()
//{
//	Print(1, string("xxxxx"), 2.2);
//	return 0;
//}
// List.h

//#include<iostream>
//#include<string>
//using namespace std;
//namespace sl
//{
//    template<class T>
//    struct ListNode
//    {
//        ListNode<T>* _next;
//        ListNode<T>* _prev;
//
//        T _data;
//
//        ListNode(T&& data)
//            :_next(nullptr)
//            , _prev(nullptr)
//            , _data(move(data))
//        {
//        }
//
//        template <class... Args>
//        ListNode(Args&&... args)
//            : _next(nullptr)
//            , _prev(nullptr)
//            , _data(std::forward<Args>(args)...)
//        {
//        }
//    };
//
//    template<class T, class Ref, class Ptr>
//    struct ListIterator
//    {
//        typedef ListNode<T> Node;
//        typedef ListIterator<T, Ref, Ptr> Self;
//        Node* _node;
//
//        ListIterator(Node* node)
//            :_node(node)
//        {
//        }
//
//        // ++it;
//        Self& operator++()
//        {
//            _node = _node->_next;
//            return *this;
//        }
//
//        Self& operator--()
//        {
//            _node = _node->_prev;
//            return *this;
//        }
//
//        Ref operator*()
//        {
//            return _node->_data;
//        }
//
//        bool operator!=(const Self& it)
//        {
//            return _node != it._node;
//        }
//    };
//
//    template<class T>
//    class list
//    {
//        typedef ListNode<T> Node;
//    public:
//        typedef ListIterator<T, T&, T*> iterator;
//        typedef ListIterator<T, const T&, const T*> const_iterator;
//
//        iterator begin()
//        {
//            return iterator(_head->_next);
//        }
//
//        iterator end()
//        {
//            return iterator(_head);
//        }
//
//        void empty_init()
//        {
//            _head = new Node();
//            _head->_next = _head;
//            _head->_prev = _head;
//        }
//
//        list()
//        {
//            empty_init();
//        }
//
//        void push_back(const T& x)
//        {
//            insert(end(), x);
//        }
//
//        void push_back(T&& x)
//        {
//            insert(end(), move(x));
//        }
//
//        iterator insert(iterator pos, const T& x)
//        {
//            Node* cur = pos._node;
//            Node* newnode = new Node(x);
//            Node* prev = cur->_prev;
//
//            // prev newnode cur
//            prev->_next = newnode;
//            newnode->_prev = prev;
//            newnode->_next = cur;
//            cur->_prev = newnode;
//
//            return iterator(newnode);
//        }
//
//        iterator insert(iterator pos, T&& x)
//        {
//            Node* cur = pos._node;
//            Node* newnode = new Node(move(x));
//            Node* prev = cur->_prev;
//
//            // prev newnode cur
//            prev->_next = newnode;
//            newnode->_prev = prev;
//            newnode->_next = cur;
//            cur->_prev = newnode;
//
//            return iterator(newnode);
//        }
//
//        template <class... Args>
//        void emplace_back(Args&&... args)
//        {
//            insert(end(), std::forward<Args>(args)...);
//        }
//
//        // 原理：本质编译器根据可变参数模板生成对应参数的函数
//        /*void emplace_back(string& s)
//        {
//            insert(end(), std::forward<string>(s));
//        }
//
//        void emplace_back(string&& s)
//        {
//            insert(end(), std::forward<string>(s));
//        }
//
//        void emplace_back(const char* s)
//        {
//            insert(end(), std::forward<const char*>(s));
//        }
//        */
//
//        template <class... Args>
//        iterator insert(iterator pos, Args&&... args)
//        {
//            Node* cur = pos._node;
//            Node* newnode = new Node(std::forward<Args>(args)...);
//            Node* prev = cur->_prev;
//
//            // prev newnode cur
//            prev->_next = newnode;
//            newnode->_prev = prev;
//            newnode->_next = cur;
//            cur->_prev = newnode;
//
//            return iterator(newnode);
//        }
//    private:
//        Node* _head;
//    };
//}
//
//// Test.cpp
//
//// emplace_back总体而言是更高效，推荐以后使用emplace系列替代insert和push系列
//int main()
//{
//    sl::list<string> lt;
//    // 传左值，跟push_back一样，走拷贝构造
//    string s1("111111111111");
//    lt.emplace_back(s1);
//    cout << "*********************************" << endl;
//
//    // 右值，跟push_back一样，走移动构造
//    lt.emplace_back(move(s1));
//    cout << "*********************************" << endl;
//
//    // 直接把构造string参数包往下传，直接用string参数包构造string
//    // 这里达到的效果是push_back做不到的
//    lt.emplace_back("111111111111");
//    cout << "*********************************" << endl;
//
//    sl::list<pair<string, int>> lt1;
//    // 跟push_back一样
//    // 构造pair + 拷贝/移动构造pair到list的节点中data上
//    pair<string, int> kv("苹果", 1);
//    lt1.emplace_back(kv);
//    cout << "*********************************" << endl;
//
//    // 跟push_back一样
//    lt1.emplace_back(move(kv));
//    cout << "*********************************" << endl;
//
//    // 直接把构造pair参数包往下传，直接用pair参数包构造pair
//    // 这里达到的效果是push_back做不到的
//    lt1.emplace_back("苹果", 1);
//    cout << "*********************************" << endl;
//
//    return 0;
//}
//
//// emplace_back总体而言是更高效，推荐以后使用emplace系列替代insert和push系列
//#include <iostream>
//#include <string>
//
//class Person
//{
//public:
//    Person(const char* name = "", int age = 0)
//        : _name(name)
//        , _age(age)
//    {
//    }
//
//    Person(const Person& p)
//        : _name(p._name)
//        , _age(p._age)
//    {
//    }
//
//    Person(Person&& p) = default;
//    //Person(const Person& p) = delete;
//
//private:
//    std::string _name;
//    int _age;
//};
//
//int main()
//{
//    Person s1;
//    Person s2 = s1;
//    Person s3 = std::move(s1);
//    return 0;
//}

//#include <iostream>
//using namespace std;
//
//int x = 0;
//// 捕捉列表必须为空，因为全局变量不⽤捕捉就可以⽤，没有可被捕捉的变量
//auto func1 = []()
//	{
//		x++;
//	};
//int main()
//{
//	// 只能⽤当前lambda局部域和捕捉的对象和全局对象
//	int a = 0, b = 1, c = 2, d = 3;
//	auto func1 = [a, &b]
//		{
//			// 值捕捉的变量不能修改，引⽤捕捉的变量可以修改
//			//a++;
//			b++;
//			int ret = a + b;
//			return ret;
//		};
//	cout << func1() << endl;
//	// 隐式值捕捉
//	// ⽤了哪些变量就捕捉哪些变量
//	auto func2 = [=]
//		{
//			int ret = a + b + c;
//			return ret;
//		};
//	cout << func2() << endl;
//	// 隐式引⽤捕捉
//	// ⽤了哪些变量就捕捉哪些变量
//	auto func3 = [&]
//		{
//			a++;
//			c++;
//			d++;
//		};
//	func3();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉1
//	auto func4 = [&, a, b]
//		{
//			//a++;
//			//b++;
//			c++;
//			d++;
//
//			return a + b + c + d;
//		};
//	func4();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 混合捕捉1
//	auto func5 = [=, &a, &b]
//		{
//			a++;
//			b++;
//			/*c++;
//			d++;*/
//
//			return a + b + c + d;
//		};
//	func5();
//	cout << a << " " << b << " " << c << " " << d << endl;
//
//	// 局部的静态和全局变量不能捕捉，也不需要捕捉
//	static int m = 0;
//
//	auto func6 = []
//		{
//			int ret = x + m;
//			return ret;
//		};
//
//	// 传值捕捉本质是⼀种拷贝,并且被const修饰了
//	// mutable相当于去掉const属性，可以修改了
//	// 但是修改了不会影响外⾯被捕捉的值，因为是⼀种拷贝
//	auto func7 = [=]()mutable
//		{
//			a++;
//			b++;
//			c++;
//			d++;
//			return a + b + c + d;
//		};
//	cout << func7() << endl;
//	cout << a << " " << b << " " << c << " " << d << endl;
//	return 0;
//}
//int main()
//{
//    // ⼀个简单的lambda表达式
//    auto add1 = [](int x, int y) -> int { return x + y; };
//    std::cout << add1(1, 2) << std::endl;
//
//    // 1、捕捉为空也不能省略
//    // 2、参数为空可以省略
//    // 3、返回值可以省略，可以通过返回对象自动推导
//    // 4、函数体不能省略
//    auto func1 = [] {
//        std::cout << "hello bit" << std::endl;
//        return 0;
//        };
//    func1();
//
//    int a = 0, b = 1;
//    auto swap1 = [](int& x, int& y) {
//        int tmp = x;
//        x = y;
//        y = tmp;
//        };
//    swap1(a, b);
//    std::cout << a << ":" << b << std::endl;
//
//    return 0;
//}
//#include<iostream>
//#include<vector>
//#include<algorithm>
//using namespace std;
//
//struct Goods
//{
//	string _name; // 名字
//	double _price; // 价格
//	int _evaluate; // 评价
//	// ...
//	Goods(const char* str, double price, int evaluate)
//		:_name(str)
//		, _price(price)
//		, _evaluate(evaluate)
//	{
//	}
//};
//struct ComparePriceLess
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price < gr._price;
//	}
//};
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& gl, const Goods& gr)
//	{
//		return gl._price > gr._price;
//	}
//};
//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "⾹蕉", 3, 4 }, { "橙⼦", 2.2, 3 }, { "菠萝", 1.5, 4 } };
//	// 类似这样的场景，我们实现仿函数对象或者函数指针⽀持商品中
//	// 不同项的⽐较，相对还是⽐较⿇烦的，那么这⾥lambda就很好⽤了
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price < g2._price;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price > g2._price;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate < g2._evaluate;
//		});
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._evaluate > g2._evaluate;
//		});
//	return 0;
//}

//#include<functional>
//#include<iostream>
//
//int f(int a, int b)
//{
//    return a + b;
//}
//
//struct Functor
//{
//public:
//    int operator() (int a, int b)
//    {
//        return a + b;
//    }
//};
//
//class Plus
//{
//public:
//    Plus(int n = 10)
//        :_n(n)
//    {
//    }
//
//    static int plusi(int a, int b)
//    {
//        return a + b;
//    }
//
//    double plusd(double a, double b)
//    {
//        return (a + b) * _n;
//    }
//
//private:
//    int _n;
//};
//
//int main()
//{
//    // 包装各种可调用对象
//    std::function<int(int, int)> f1 = f;
//    std::function<int(int, int)> f2 = Functor();
//    std::function<int(int, int)> f3 = [](int a, int b) {return a + b; };
//
//    std::cout << f1(1, 1) << std::endl;
//    std::cout << f2(1, 1) << std::endl;
//    std::cout << f3(1, 1) << std::endl;
//
//    // 包装静态成员函数
//    std::function<int(int, int)> f4 = &Plus::plusi;
//    std::cout << f4(1, 1) << std::endl;
//
//    // 包装普通成员函数
//    std::function<double(Plus*, double, double)> f5 = &Plus::plusd;
//    Plus pd;
//    std::cout << f5(&pd, 1.1, 1.1) << std::endl;
//
//    std::function<double(Plus, double, double)> f6 = &Plus::plusd;
//    std::cout << f6(pd, 1.1, 1.1) << std::endl;
//    std::cout << f6(pd, 1.1, 1.1) << std::endl;
//
//    std::function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//    std::cout << f7(std::move(pd), 1.1, 1.1) << std::endl;
//    std::cout << f7(Plus(), 1.1, 1.1) << std::endl;
//
//    return 0;
//}
